package com.fengkai.filepost.pdfoutstream.test.ODsolutions;


import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Callable;

/**
 * @author Fengkai
 * @creat 2023/4/13
 * 请实现一个简易内存池
 * 根据请求命令完成内存分配和释放,内存池支持两种操作命令,REQUEST和RELEASE其格式为,REQUEST=请求的内存大小,表示请求分配指定大小内存,如果分配成功，返回分配到的内存首地址,如果内存不足，或指定的大小为零则输出error,RELEASE=释放的内存首地址
 * 表示释放掉之前分配的内存,释放成功无需输出,如果释放不存在的首地址,则输出error
 * 注意：
 * 内存池总大小为 100 字节
 * 内存池地址分配必须是连续内存，并优先从低地址分配,内存释放后可被再次分配，已释放的内存在空闲时不能被二次释放,不会释放已申请的内存块的中间地址
 * 释放操作只是针对首地址所对应的单个内存块进行操作，不会影响其他内存块
 * 输入
 * 首行为整数N
 * 表示操作命令的个数
 * 取值范围0<N<=100
 * 接下来的N行
 * 每行将给出一个操作命令
 * 操作命令和参数之间用”=“分割
 * 输出见题目输出要求
 */
public class SimpleRom  {
    //内存
    static int[] rom = new int[100];
    //申请的首地址和长度
    static Map<Integer, Integer> indexLength = new HashMap<>();

    public static void main (String[] args) {
        getRomDistribution("REQUEST=5");
        getRomDistribution("REQUEST=91");
        getRomDistribution("RELEASE=5");
        getRomDistribution("REQUEST=20");
        getRomDistribution("REQUEST=10");

    }

    public static void getRomDistribution (String input) {
        int num = Integer.parseInt(input.substring(input.indexOf("=") + 1, input.length()));
        if (input.contains("REQUEST")) {
            //请求内存
            int i = requestRom(num);
            if (i == -1) {
                System.out.println("error");
            }else {
                System.out.println(i);
            }
        } else {
            //释放内存
            int i = releaseRom(num);
            if (i == -1) {
                System.out.println("error");
            }else {
                //成功释放不输出
            }
        }
    }

    private  static synchronized int requestRom (int length) {

        if (length <= 0 || length > 100) {
            return -1;
        }
        int ans = -1;
        int left = 0;
        int right = left;
        int index = 0;
        out:
        while (left < 100 && right < 100) {
            if (rom[left] == 0) {
                for (right = left; right < rom.length; right++) {
                    if (rom[right] == 1 || (right - left) == length) {
                        break;
                    }
                }
                if (right - left < length) {
                    left = right + 1;
                    continue out;
                } else {
                    for (int i = left; i < right; i++) {
                        rom[i] = 1;
                    }
                    indexLength.put(left, length);
                    ans = left;
                    break out;
                }
            } else {
                left++;
                right = left;
            }
        }
        return ans;
    }

    private static synchronized int releaseRom (int index) {
        if (indexLength.get(index) == null) {
            return -1;
        }
        Integer size = indexLength.get(index);
        //释放内存
        for (int i = index; i < size + index; i++) {
            rom[i] = 0;
        }

        return 0;
    }

}
